import numpy as np
import librosa#   librosa是python的一个音频处理的包
import tensorflow as tf
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
import tensorflow.keras.layers as layers
import os
from sklearn.model_selection import train_test_split
from tensorflow.keras import losses,optimizers

ID=[]#left-0-0.wav
labels=[]#  left  right stop

train_path='voice_data2/train'
test_path='voice_data2/test'
def readData(path):
    for i,class_name in enumerate(os.listdir(path)):
        class_path=os.path.join(path,class_name)
        if not os.listdir(class_path):
            continue
        else:
            for voice_name in os.listdir(class_path):
                voice_path=os.path.join(class_path,voice_name)
                if os.path.isfile(voice_path):
                    ID.append(voice_name)
                    labels.append(i)
    return ID,labels

train_ID,train_label=readData(train_path)
# print(train_label)

def extract_features(path):
    features=[]
    for class_name in os.listdir(path):
        class_path=os.path.join(path,class_name)
        if os.listdir(class_path):
            for voice_name in os.listdir(class_path):
                voice_path=os.path.join(class_path,voice_name)
                if not os.listdir(class_path):
                    continue
                else:
                    y, sr = librosa.load(voice_path)  #librosa.load 用途：读取文件，可以是wav、mp3等格式。 #返回值  y : 音频的信号值，类型是ndarray  sr : 采样率
                    mfccs = np.mean(librosa.feature.mfcc(y, sr=sr, n_mfcc=100).T, axis=0)#使用librosa包进行mfcc特征参数提取
                    #mfcc_data=librosa.feature.mfcc(y=y, sr=sr,S=None, n_mfcc=20, dct_type=2, norm=‘ortho’,n_fft=N_FFT,hop_length=int(N_FFT/4))
                    #参数
                    # y：语音数据
                    # sr：y的采样率  #采样率是将模拟量转换为数字量时对信号转换的频率（即每秒采集次数），这个频率越高，单位时间内对信号的采集就越多，信号中的信息就保留越多，丢失信息就少，转换出的数字量就能准确反映信号的数值，
                    # n_mfcc：要返回的MFCC数量
                    features.append(mfccs)
    return features

features_train=extract_features(train_path)
features_test=extract_features(test_path)
# print(f'''features_train:{type(features_train)}''')#features_train:<class 'list'>

X_train=np.array(features_train)
Y_train=train_label
Y_train=np.reshape(Y_train,(-1,1))
print(f'''转变前Y_train:{Y_train}''')#left  0  right  1  stop  2
X_test=np.array(features_test)

print(f'''转变后Y_train：{Y_train}''')


x_train,x_val,y_train,y_val=train_test_split(X_train,Y_train,train_size=0.7,shuffle=True)
print(f'''形状''')
print(x_train.shape,y_train.shape)#(84, 100) (84, 1)

model=tf.keras.Sequential()#建立顺序模型
model.add(layers.Dense(input_shape=(100,), units= 200,activation='relu'))#全连接
model.add(layers.Dense(200,activation='relu'))
model.add(layers.Dense(200,activation='relu'))
model.add(layers.Dense(3,activation='softmax'))

model.summary()
model.compile(optimizer=optimizers.Adam(lr=0.001),loss=losses.SparseCategoricalCrossentropy(),metrics=['accuracy'])

hist=model.fit(x_train,y_train,epochs=200,validation_data=(x_val,y_val))

plt.title('Train Loss values over 200 epochs:')
plt.plot(hist.history['loss'],color='red',linewidth=2)
plt.show()


plt.title('Train accuracy values over 200 epochs:')
plt.plot(hist.history['accuracy'],color='purple')
plt.show()
Y_pred=model.predict(X_test)
# print(f'''.....''')
# print(Y_pred)

Y_pred=np.argmax(Y_pred,axis=1)

print(f'预测')
print(Y_pred)
for i in Y_pred:
    if i==0:
        print(f'''pre:left''')
    elif i==1:
        print(f'''pre:right''')
    else:
        print(f'''pre:stop''')
